using System;
using Microsoft.SmallBasic.Library;

namespace SmallBasicFun.Quizes
{
	public class SpiderQuiz : IQuiz
	{
		private  int circleCount;
		private  bool mock;
		private  int adjustCount;
		private  int angle;

		
		public  Question Question1Circle
		{
			get { return Quiz.questions[0]; }
		}
		public  Question Question2CircleAround
		{
			get { return Quiz.questions[1]; }
		}
		public  Question Question3Grow
		{
			get { return Quiz.questions[2]; }
		}
		public  Question Question4Shrink
		{
			get { return Quiz.questions[3]; }
		}
		public  Question Question5Expand
		{
			get { return Quiz.questions[4]; }
		}
		

		public  void StartTest()
		{
			Tortoise.SetSpeed(10);
			GradeResults();
			InitializeScreen();
			DrawSuccess();
			Quiz.DisplayScores(5,400);
		}

		private  void DrawSuccess()
		{
			mock = false;
			Tortoise.SetSpeed(10);
			Tortoise.SetPenWidth(15);

			ColorWheel.AddColor(Colors.Black);
			ColorWheel.AddColor(Colors.White);
			ProgramWindow.SetBackgroundColor(Colors.Silver);
			Question1Circle.SetVariable("number",16);
			Question1Circle.SetVariable("length",15);
			angle = -15;
			DrawCircle();
			Question2CircleAround.Run();
			Tortoise.Hide();
		}
		private  void DrawCircle()
		{
			Question1Circle.Run();
		}





		private  void InitializeScreen()
		{
			ProgramWindow.Clear();
			ProgramWindow.SetBackgroundColor(Colors.Silver);

			Tortoise.SetPosition(150,200);
			Tortoise.SetAngle(0);
			Tortoise.Show();
		}


		private  void GradeResults()
		{
			Grade1Circle();
			Grade2CircleAround();
			Grade3Grow();
			Grade4Shrink();
			Grade5Expand();
		}

		private  void Grade1Circle()
		{
			
			Mock();
			Question1Circle.SetVariable("number", 8);
			Question1Circle.Run();
			Question1Circle.Result = 8 == circleCount;
		}		private  void Grade2CircleAround()
		{
			
			Mock();
			Question2CircleAround.SetVariable("number", 7);
			Question2CircleAround.Run();
			Question2CircleAround.Result = 21 == circleCount && 3 == adjustCount;
		}

		private  void Mock()
		{
			mock = true;
			circleCount = 0;
			adjustCount = 0;
		}

		private  void Grade3Grow()
		{
			Grade(Question3Grow, "length", (n) => n * 2.5);
		}

		private  void Grade4Shrink()
		{
			Grade(Question4Shrink, "length", (n) => n - 9);
		}
		private  void Grade5Expand()
		{
			Grade(Question5Expand, "number", (n) => n + 12);
		}

		private  void Grade(Question question, string name, Func<int, Primitive> func)
		{
			int[] points = {-1, 0, 3, 12};
			var correct = true;
			foreach (var i in points)
			{
				question.SetVariable(name, i);
				question.Run();
				Primitive number = question.GetVariable(name);
				correct = correct && func(i) == number;
			}

			question.Result = correct;
		}


		public  void Circle()
		{
			if (mock)
			{
				circleCount++;

			}
			else
			{
				Tortoise.SetPenColor(ColorWheel.GetNextColor());
				Tortoise.Turn(angle);
				Move(1);
				Tortoise.PenUp();
				Move(-1);
				Tortoise.Turn(-angle);
				Move(1);
				Question4Shrink.Run();
				Move(1);
				Question3Grow.Run();
				Tortoise.PenDown();
				Tortoise.Turn(360.0 / Question1Circle.GetVariable("number"));
			}	
		}

		private  void Move(int multiplier)
		{
			Tortoise.Move(Question1Circle.GetVariable("length")*multiplier);
		}

		public  void Adjust()
		{
			if (mock)
			{
				adjustCount++;
			}
			else
			{
				angle = angle * -1;
				ColorWheel.GetNextColor();
				Tortoise.Turn(-90);
				Tortoise.PenUp();
				Tortoise.Move(42);
				Tortoise.PenDown();
				Tortoise.Turn(90);
				Question5Expand.Run();
			}
		}
	}
}